/* eslint-disable react/self-closing-comp */
import React, { Component, Suspense } from 'react';
import { connect } from 'dva';
import GridContent from '@/components/PageHeaderWrapper/GridContent';
import PageLoading from '@/components/PageLoading';
import {
  Card,
  Button,
  Icon,
  Modal,
  message,
  Form,
  Input,
  Checkbox,
  Col,
  Row,
  Tag,
  Select,
  Radio,
  InputNumber,
} from 'antd';
import styles from '../../collect/slotCheck/index.less';

const { Option } = Select;
const formItemLayout = {
  labelCol: { span: 3 },
  wrapperCol: { span: 20 },
};

class ExtraItem extends Component {
  constructor(props) {
    super(props);
    this.state = {
      values: [],
      slotIndex: '',
      itemIndex: '',
      index: '',
      slotArr: [],
    };
  }

  delCaseItem = index => {
    const { caseArr, upDateCase } = this.props;
    caseArr.splice(index, 1);
    upDateCase(caseArr);
  };

  forMapInpuirsOption = (option, index, type) => {
    switch (type) {
      case 'obj':
        return (
          <Option key={index} value={option.dictName}>
            {option.name}
          </Option>
        );
      case 'slot':
        return (
          <Option key={option.slotId} value={option.slotId}>
            #{option.slotName}#
          </Option>
        );
      case 'api':
        return (
          <Option key={option.id} value={option.id}>
            {option.name}
          </Option>
        );
      default:
        return (
          <Option key={index} value={option}>
            {option}
          </Option>
        );
    }
  };

  forMap = (caseItem, index) => {
    const CaseElem = caseItem.conditions.map((items, itemIndex) =>
      this.forMapItemCase(items, itemIndex, index, caseItem)
    );
    const { data, selected, dialogSlots, apis } = this.props;
    const newIndex = index + 1;
    const OptionElem = data.map(this.forMapInpuirsOption);
    const DictOpElem = selected.map((item, idx) => this.forMapInpuirsOption(item, idx, 'obj'));
    const SlotOpElem = dialogSlots.map((item, idx) => this.forMapInpuirsOption(item, idx, 'slot'));

    const ApipElem = apis.map((item, idx) => this.forMapInpuirsOption(item, idx, 'api'));
    return (
      <Card
        title={`规则${newIndex}`}
        key={index}
        bordered
        className={styles.caseItem}
        extra={<Icon type="close" onClick={() => this.delCaseItem(index)} />}
      >
        <Form.Item {...formItemLayout} label="前置问题" style={{ marginBottom: 5 }}>
          <Select
            value={caseItem.condition}
            style={{ width: 120 }}
            onChange={e => this.fixCommData(index, e, 'condition')}
          >
            <Option value="none">无</Option>
            <Option value="ask">机器人问</Option>
          </Select>
          {caseItem.condition === 'ask' ? (
            <Select
              value={caseItem.askQuestion}
              style={{ width: 320, marginLeft: 10 }}
              onChange={e => this.fixCommData(index, e, 'askQuestion')}
            >
              <Option value="N">请选择</Option>
              {OptionElem}
            </Select>
          ) : (
            ''
          )}
        </Form.Item>
        <Form.Item {...formItemLayout} label="用户回复" style={{ marginBottom: 5 }}>
          <Select
            style={{ width: 120 }}
            value={caseItem.operator}
            onChange={e => this.fixCommData(index, e, 'operator')}
          >
            <Option value="N">请选择</Option>
            <Option value="contain">包含</Option>
            <Option value="not_contain">不包含</Option>
          </Select>
          {caseItem.operator !== 'N' ? (
            <span>
              <Select
                style={{ width: 120, marginLeft: 10 }}
                value={caseItem.answerType}
                onChange={e => this.fixCommData(index, e, 'answerType')}
              >
                <Option value="N">请选择</Option>
                <Option value="dict">实体</Option>
                <Option value="string">字符串</Option>
              </Select>
              {caseItem.answerType === 'string' ? (
                <Input
                  placeholder="请输入回复话术"
                  style={{ width: 220, marginLeft: 10 }}
                  onChange={e => this.fixCommData(index, e, 'value', true)}
                  value={caseItem.value}
                />
              ) : (
                <Select
                  style={{ width: 120, marginLeft: 10 }}
                  value={caseItem.value}
                  onChange={e => this.fixCommData(index, e, 'value')}
                >
                  <Option value="N">无</Option>
                  {DictOpElem}
                </Select>
              )}
            </span>
          ) : (
            ''
          )}
        </Form.Item>
        <Row>{CaseElem}</Row>
        <Form.Item {...formItemLayout} label="抽取结果" style={{ marginBottom: 5 }}>
          <Select
            value={caseItem.resultType}
            style={{ width: 120 }}
            onChange={e => this.fixCommData(index, e, 'resultType')}
          >
            <Option value="slot">词槽</Option>
            <Option value="filter">筛选规则</Option>
          </Select>
          {caseItem.resultType === 'slot' ? (
            <span>
              <Select
                value={caseItem.resultSlotId}
                style={{ width: 120, marginLeft: 10 }}
                onChange={e => this.fixCommData(index, e, 'resultSlotId')}
              >
                <Option value="none">无</Option>
                {SlotOpElem}
              </Select>
            </span>
          ) : (
            <span>
              <Select
                value={caseItem.filterType}
                style={{ width: 120, marginLeft: 10 }}
                onChange={e => this.fixCommData(index, e, 'filterType')}
              >
                <Option value="N">请选择</Option>
                <Option value="number">数值型</Option>
                <Option value="Date">日期型</Option>
                <Option value="time">时间型</Option>
                <Option value="timeDate">时间日期型</Option>
                <Option value="string">字符串型</Option>
              </Select>
              <span style={{ marginLeft: 10 }}>接口返回字段</span>
              <Select
                value={caseItem.fieldResponse}
                style={{ width: 120, marginLeft: 10 }}
                onChange={e => this.fixCommData(index, e, 'fieldResponse')}
              >
                <Option value="N">请选择</Option>
                {ApipElem}
              </Select>
              {caseItem.filterType === 'number' ? <>
                <Select
                  value={caseItem.resultFilterRule}
                  style={{ width: 120, marginLeft: 10 }}
                  onChange={e => this.fixCommData(index, e, 'resultFilterRule')}
                >
                  <Option value="N">请选择</Option>
                  <Option value="great_than">大于</Option>
                  <Option value="less_than">小于</Option>
                  <Option value="great_than_equal">大于等于</Option>
                  <Option value="less_than_equal">小于等于</Option>
                  <Option value="equal">等于</Option>
                  <Option value="no_equal">不等于</Option>
                </Select>
              </> : caseItem.filterType === 'Date' ? <>
                <Select
                  value={caseItem.resultFilterRule}
                  style={{ width: 120, marginLeft: 10 }}
                  onChange={e => this.fixCommData(index, e, 'resultFilterRule')}
                >
                  <Option value="N">请选择</Option>
                  <Option value="new_than">早于</Option>
                  <Option value="old_than">晚于</Option>
                  <Option value="equal">等于</Option>
                  <Option value="no_equal">不等于</Option>
                </Select>
              </> : caseItem.filterType === 'string' ? <>
                <Select
                  value={caseItem.resultFilterRule}
                  style={{ width: 120, marginLeft: 10 }}
                  onChange={e => this.fixCommData(index, e, 'resultFilterRule')}
                >
                  <Option value="N">请选择</Option>
                  <Option value="contain">包含</Option>
                  <Option value="not_contain">不包含</Option>
                  <Option value="equal">等于</Option>
                  <Option value="not_equal">不等于</Option>
                </Select>
              </> : <>
                <Select
                  value={caseItem.resultFilterRule}
                  style={{ width: 120, marginLeft: 10 }}
                  onChange={e => this.fixCommData(index, e, 'resultFilterRule')}
                >
                  <Option value="N">请选择</Option>
                  <Option value="equal">等于</Option>
                  <Option value="not_equal">不等于</Option>
                </Select>
              </>}
              <span style={{ marginLeft: 10 }}>词槽</span>
              <Select
                value={caseItem.resultSlotId}
                style={{ width: 120, marginLeft: 10 }}
                onChange={e => this.fixCommData(index, e, 'resultSlotId')}
              >
                <Option value="none">无</Option>
                {SlotOpElem}
              </Select>
            </span>
          )}
        </Form.Item>
      </Card>
    );
  };

  addSlot = index => {
    const { caseArr } = this.props;
    caseArr[index].slotIds.push({});
    this.upDataByCallBack(caseArr);
  };

  delSlotByIndex = (itemIndex, index) => {
    const { caseArr } = this.props;
    caseArr[index].slotIds.splice(itemIndex, 1);
    this.upDataByCallBack(caseArr);
  };

  handleSlotSelectChange = (val, itemIndex, index) => {
    const { caseArr } = this.props;
    caseArr[index].slotIds[itemIndex].slotId = val;
    this.upDataByCallBack(caseArr);
  };

  forMapItemCase = (items, itemIndex, index, caseItem) => {
    switch (items.itemType) {
      case undefined:
        return (
          <div>
            {items.map((commItem, commItemIndex) =>
              this.forMapCommCase(commItem, commItemIndex, itemIndex, index, items, caseItem)
            )}
            {itemIndex === caseItem.conditions.length - 1 ? (
              <Button
                htmlType="button"
                type="primary"
                size="small"
                onClick={() => this.addGroupCase(itemIndex, index)}
                className={styles.addGroupItem}
              >
                添加条件组
              </Button>
            ) : (
              ''
            )}
          </div>
        );
      default:
        return this.forMapSpecialCase(items, itemIndex);
    }
  };

  forMapCommCase = (commItem, commItemIndex, itemIndex, index, items, caseItem) => {
    switch (commItem.itemType) {
      case 'case':
        return this.renderSlotCase(commItem, commItemIndex, itemIndex, index, items, caseItem);
      default:
        return this.renderLogicCase(commItem);
    }
  };

  forMapSpecialCase = (specialItem, specialItemIndex) => {
    return (
      <div key={specialItemIndex}>
        <div className={styles.orItem}>或</div>
      </div>
    );
  };

  renderSlotCase = (slotItem, slotIndex, itemIndex, index, items) => {
    return (
      <Row key={slotIndex}>
        <Col style={{ marginLeft: 30 }}>
          <Select
            defaultValue="N"
            value={slotItem.measure}
            className={styles.selectItem}
            onChange={e => this.updataItemCommonData(e, slotIndex, itemIndex, index, 'measure')}
          >
            <Option value="N">请选择</Option>
            <Option value="left">左侧</Option>
            <Option value="right">右侧</Option>
            <Option value="length">长度</Option>
          </Select>
          {slotItem.measure === 'length' ? (
            <span>
              <Select
                defaultValue="N"
                value={slotItem.operator}
                className={styles.selectItem}
                style={{ width: 120 }}
                onChange={e =>
                  this.updataItemCommonData(e, slotIndex, itemIndex, index, 'operator')
                }
              >
                <Option value="N">请选择</Option>
                <Option value="gt">大于</Option>
                <Option value="lt">小于</Option>
                <Option value="eq">等于</Option>
                <Option value="lte">小于等于</Option>
                <Option value="gte">大于等于</Option>
              </Select>
              <InputNumber
                value={slotItem.value}
                style={{ width: 120 }}
                onChange={e => this.updataItemCommonData(e, slotIndex, itemIndex, index, 'value')}
              />
            </span>
          ) : (
            <span>
              <Select
                defaultValue="N"
                value={slotItem.limit}
                className={styles.selectItem}
                style={{ width: 180 }}
                onChange={e => this.updataItemCommonData(e, slotIndex, itemIndex, index, 'limit')}
              >
                <Option value="N">请选择</Option>
                <Option value="1">1个字符以内</Option>
                <Option value="2">2个字符以内</Option>
                <Option value="3">3个字符以内</Option>
                <Option value="4">4个字符以内</Option>
                <Option value="5">5个字符以内</Option>
                <Option value="6">6个字符以内</Option>
                <Option value="7">7个字符以内</Option>
                <Option value="8">8个字符以内</Option>
                <Option value="9">9个字符以内</Option>
                <Option value="10">10个字符以内</Option>
                <Option value="11">不限字符</Option>
              </Select>
              {slotItem.limit !== 'N' ? (
                <span>
                  <Select
                    defaultValue="N"
                    value={slotItem.operator}
                    className={styles.selectItem}
                    style={{ width: 120 }}
                    onChange={e =>
                      this.updataItemCommonData(e, slotIndex, itemIndex, index, 'operator')
                    }
                  >
                    <Option value="N">请选择</Option>
                    <Option value="contain">包含</Option>
                    <Option value="not_contain">不包含</Option>
                  </Select>
                  <Input
                    value={slotItem.value}
                    style={{ width: 120 }}
                    onChange={e => this.updataInputData(e, slotIndex, itemIndex, index, 'value')}
                  />
                </span>
              ) : (
                ''
              )}
            </span>
          )}

          <Icon
            type="close-circle"
            onClick={() => this.delCaseItemByCloseIcon(slotItem, slotIndex, itemIndex, index)}
            style={{ marginLeft: 5, cursor: 'pointer' }}
          />
        </Col>
        <Col style={{ marginLeft: 30 }}>
          {slotIndex === items.length - 1 ? (
            <span
              className={styles.addOneCase}
              onClick={() => this.addOnecase(slotItem, slotIndex, itemIndex, index)}
            >
              {' '}
              <Icon type="plus" />
              添加条件
            </span>
          ) : (
            ''
          )}
        </Col>
      </Row>
    );
  };

  forMapSlotsOption = option => {
    return (
      <Option key={option.slotId} value={option.slotId}>
        #{option.slotName}#
      </Option>
    );
  };

  renderLogicCase = (logicItem, logicIndex) => {
    return (
      <div key={logicIndex} className={styles.andItem}>
        且
      </div>
    );
  };

  addCase = () => {
    const { caseArr } = this.props;
    caseArr.push({
      condition: 'none',
      askQuestion: 'N',
      operator: 'N',
      answerType: 'N',
      value: 'N',
      conditions: [
        [
          {
            itemType: 'case',
            measure: 'N',
            limit: 'N',
            operator: 'N',
            value: ' ',
          },
        ],
      ],
      resultSlotId: 'none',
      resultType: 'slot',
      filterType: 'N',
      fieldResponse: 'N',
      resultFilterRule: 'N',
    });
    const { upDateCase } = this.props;
    upDateCase(caseArr);
  };

  upDataByCallBack = res => {
    const { upNewData } = this.props;
    upNewData(res);
  };

  addOnecase = (item, slotIndex, itemIndex, rootIndex) => {
    const { caseArr } = this.props;
    caseArr[rootIndex].conditions[itemIndex].push({
      itemType: 'logic',
      value: 'and',
    });
    caseArr[rootIndex].conditions[itemIndex].push({
      itemType: 'case',
      measure: 'N',
      limit: 'N',
      operator: 'N',
      value: ' ',
    });
    this.upDataByCallBack(caseArr);
  };

  addGroupCase = (itemIndex, rootIndex) => {
    const { caseArr } = this.props;
    caseArr[rootIndex].conditions.push({
      itemType: 'logic',
      value: 'or',
    });
    caseArr[rootIndex].conditions.push([
      {
        itemType: 'case',
        measure: 'N',
        limit: 'N',
        operator: 'N',
        value: ' ',
      },
    ]);
    this.upDataByCallBack(caseArr);
  };

  delCaseItemByCloseIcon = (item, slotIndex, itemIndex, rootIndex) => {
    const { caseArr } = this.props;
    if (slotIndex === 0 && itemIndex === 0 && rootIndex === 0) {
      return false;
    }

    if (caseArr[rootIndex].conditions[itemIndex].length > 1) {
      if (slotIndex === 0) {
        if (caseArr[rootIndex].conditions[itemIndex][slotIndex + 1].itemType !== undefined) {
          caseArr[rootIndex].conditions[itemIndex].splice(slotIndex, 1);
          caseArr[rootIndex].conditions[itemIndex].splice(slotIndex, 1);
        }
      } else if (caseArr[rootIndex].conditions[itemIndex][slotIndex - 1].itemType !== undefined) {
        caseArr[rootIndex].conditions[itemIndex].splice(slotIndex, 1);
        caseArr[rootIndex].conditions[itemIndex].splice(slotIndex - 1, 1);
      }
    } else if (caseArr[rootIndex].conditions[itemIndex - 1].itemType !== undefined) {
      caseArr[rootIndex].conditions[itemIndex].splice(slotIndex, 1);
      caseArr[rootIndex].conditions.splice(itemIndex - 1, 1);
    }
    this.upDataByCallBack(caseArr);
  };

  updataItemCommonData = (e, slotIndex, itemIndex, index, type) => {
    const { caseArr } = this.props;
    caseArr[index].conditions[itemIndex][slotIndex][type] = e;
    if (type === 'measure') {
      caseArr[index].conditions[itemIndex][slotIndex].value = '';
      caseArr[index].conditions[itemIndex][slotIndex].operator = 'N';
    }
    this.upDataByCallBack(caseArr);
  };

  updataInputData = (e, slotIndex, itemIndex, index, type) => {
    const { caseArr } = this.props;
    caseArr[index].conditions[itemIndex][slotIndex][type] = e.target.value;
    this.upDataByCallBack(caseArr);
  };

  fixCommData = (index, e, type, isString) => {
    const { caseArr } = this.props;
    caseArr[index][type] = e;
    if (isString) {
      caseArr[index].value = e.target.value;
    }
    this.upDataByCallBack(caseArr);
  };

  render() {
    const { caseArr } = this.props;
    const CaseChild = caseArr.map(this.forMap);
    const { values, slotIndex, itemIndex, index, slotArr } = this.state;
    return (
      <GridContent>
        <Suspense fallback={<PageLoading />}>
          {CaseChild}
          <div className={styles.caseItem}>
            <Button
              htmlType="button"
              type="primary"
              size="small"
              onClick={() => this.addCase()}
              className={styles.addCaseItem}
            >
              添加规则
            </Button>
          </div>
        </Suspense>
      </GridContent>
    );
  }
}

export default connect(({ user }) => ({
  currentUser: user.currentUser,
}))(Form.create()(ExtraItem));
